/******************************************************************************
 copyright (C), 2018, hisilicon tech. co., ltd.
******************************************************************************
file name     : pm.h
version       : initial draft
author        : hisilicon multimedia software group
created       : 2018/09/17
last modified :
description   :
function list :
******************************************************************************/
#ifndef __PM_H__
#define __PM_H__

#include "hi_osal.h"

#include "hi_defines.h"
#include "hi_comm_pm.h"

#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif /* __cplusplus */

/*debug need*/
#define NEED_MEM_INFO 0

#define CALL_DEV_NUM        16
#define CALL_MODE_NUM      3

#if 0
extern  osal_spinlock_t     g_pm_lock;
#define PM_SPIN_LOCK       valg_lock(&g_pm_lock, &(flags))
#define PM_SPIN_UNLOCK     valg_un_lock(&g_pm_lock, &(flags))
#endif

#define PM_DOWN_SEM()\
    do{\
        if (osal_down_interruptible(&g_pm_sem))\
            return -ERESTARTSYS;\
    }while(0)

#define PM_UP_SEM()    osal_up(&g_pm_sem)


#define PM_MIN(a, b)         (((a) > (b)) ? (b) : (a))

#define PM_TIME_DIFF(time_end, time_begin) (hi_u32)((time_end.tv_sec - time_begin.tv_sec)*1000000LLU + time_end.tv_usec - time_begin.tv_usec)

#define pm_do_gettimeofday(ptime)  \
    do{\
        osal_gettimeofday(ptime);\
    }while(0)\

#define CHECK_NULL_PTR(ptr)\
    do{\
        hi_s32 ret;\
        ret = pm_check_null_ptr((hi_void*)ptr);\
        if(HI_SUCCESS != ret)\
        {\
            return ret;\
        }\
    }while(0)

#define PM_CHECK_MOD_STARTED()\
    do{\
        hi_s32 ret;\
        ret = pm_check_mod_start();\
        if(HI_SUCCESS != ret)\
        {\
            return ret;\
        }\
    }while(0)


#define PM_CHECK_MODID(modid, callermodid)\
    do{\
        if(PM_MAX_CALLER_MOD_NUM <= (callermodid))\
        {\
            HI_TRACE_PM(HI_DBG_ERR,"input illegal param: mod id %d\n",(modid));\
            return HI_ERR_PM_ILLEGAL_PARAM;\
        }\
    }while(0)


typedef enum pm_mod_state_e{
    PM_MOD_STATE_STOPPED     = 0,
    PM_MOD_STATE_STARTED     = 1,
    PM_MOD_STATE_STOPPING     = 2,

    PM_MOD_TATE_BUTT
} pm_mod_state;

typedef struct pm_dbg_info_s{

    hi_s32 reserv;
} pm_dbg_info;

/*PM moudle context */
typedef struct pm_ctx_s{
    hi_s32 domain_num;
    hi_bool pm_enable;

    pm_dbg_info s_pm_dbg_info; /*PM debug info*/

} pm_ctx;


hi_s32 pm_check_null_ptr(hi_void *ptr);
hi_s32 pm_check_mod_start(hi_void);

void pm_mod_init(void);
void pm_mod_exit(void);


#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif /* __cplusplus */

#endif /*endof __PM_H__*/
